home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Technology Seed / Jan. '98 ATS.toast / QuickTime™ 3.0b11 / QTPublicInterfaces / CIncludes / Endian.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-12  |  10.2 KB  |  373 lines  |  [TEXT/MPS ]

  1. /*
  2.      File:        Endian.h
  3.  
  4.      Contains:    QuickTime Interfaces
  5.  
  6.      Version:    Technology:    QuickTime 3.0
  7.                  Release:    QuickTime 3.0 Beta
  8.  
  9.      Copyright:    © 1997 by Apple Computer, Inc., all rights reserved
  10.  
  11.      Bugs?:        Please include the the file and version information (from above) with
  12.                  the problem description.  Developers belonging to one of the Apple
  13.                  developer programs can submit bug reports to:
  14.  
  15.                      devsupport@apple.com
  16.  
  17. */
  18. #ifndef __ENDIAN__
  19. #define __ENDIAN__
  20.  
  21. #ifndef __CONDITIONALMACROS__
  22. #include <ConditionalMacros.h>
  23. #endif
  24. #ifndef __MACTYPES__
  25. #include <MacTypes.h>
  26. #endif
  27.  
  28.  
  29.  
  30. #if PRAGMA_ONCE
  31. #pragma once
  32. #endif
  33.  
  34. #ifdef __cplusplus
  35. extern "C" {
  36. #endif
  37.  
  38. #if PRAGMA_IMPORT
  39. #pragma import on
  40. #endif
  41.  
  42. #if PRAGMA_STRUCT_ALIGN
  43.     #pragma options align=mac68k
  44. #elif PRAGMA_STRUCT_PACKPUSH
  45.     #pragma pack(push, 2)
  46. #elif PRAGMA_STRUCT_PACK
  47.     #pragma pack(2)
  48. #endif
  49.  
  50. /*
  51.     This file provides Endian Flipping routines for dealing with converting data
  52.     between Big-Endian and Little-Endian machines.  These routines are useful
  53.     when writing code to compile for both Big and Little Endian machines and  
  54.     which must handle other endian number formats, such as reading or writing 
  55.     to a file or network packet.
  56.     
  57.     These routines are named as follows:
  58.     
  59.         Endian<U><W>_<S>to<D>
  60.  
  61.     where
  62.         <U>    is whether the integer is signed ('S') or unsigned ('U')
  63.         <W> is integer bit width: 16, 32, or 64 
  64.         <S> is the source endian format: 'B' for big, 'L' for little, or 'N' for native
  65.         <D> is the destination endian format: 'B' for big, 'L' for little, or 'N' for native
  66.     
  67.     For example, to convert a Big Endian 32-bit unsigned integer to the current native format use:
  68.         
  69.         long i = EndianU32_BtoN(data);
  70.         
  71.     This file is set up so that the function macro to nothing when the target runtime already
  72.     is the desired format (e.g. on Big Endian machines, EndianU32_BtoN() macros away).
  73.             
  74.     If long long's are not supported, you cannot get 64-bit quantities as a single value.
  75.     The macros are not defined in that case.
  76.     
  77.     
  78.     
  79.                                 <<< W A R N I N G >>>
  80.     
  81.     It is very important not to put any autoincrements inside the macros.  This 
  82.     will produce erroneous results because each time the address is accessed in the macro, 
  83.     the increment occurs.
  84.     
  85.  */
  86. EXTERN_API_C( SInt16 )
  87. EndianS16_BtoN                    (SInt16                 value);
  88.  
  89. EXTERN_API_C( SInt16 )
  90. EndianS16_NtoB                    (SInt16                 value);
  91.  
  92. EXTERN_API_C( SInt16 )
  93. EndianS16_LtoN                    (SInt16                 value);
  94.  
  95. EXTERN_API_C( SInt16 )
  96. EndianS16_NtoL                    (SInt16                 value);
  97.  
  98. EXTERN_API_C( SInt16 )
  99. EndianS16_LtoB                    (SInt16                 value);
  100.  
  101. EXTERN_API_C( SInt16 )
  102. EndianS16_BtoL                    (SInt16                 value);
  103.  
  104. EXTERN_API_C( UInt16 )
  105. EndianU16_BtoN                    (UInt16                 value);
  106.  
  107. EXTERN_API_C( UInt16 )
  108. EndianU16_NtoB                    (UInt16                 value);
  109.  
  110. EXTERN_API_C( UInt16 )
  111. EndianU16_LtoN                    (UInt16                 value);
  112.  
  113. EXTERN_API_C( UInt16 )
  114. EndianU16_NtoL                    (UInt16                 value);
  115.  
  116. EXTERN_API_C( UInt16 )
  117. EndianU16_LtoB                    (UInt16                 value);
  118.  
  119. EXTERN_API_C( UInt16 )
  120. EndianU16_BtoL                    (UInt16                 value);
  121.  
  122. EXTERN_API_C( SInt32 )
  123. EndianS32_BtoN                    (SInt32                 value);
  124.  
  125. EXTERN_API_C( SInt32 )
  126. EndianS32_NtoB                    (SInt32                 value);
  127.  
  128. EXTERN_API_C( SInt32 )
  129. EndianS32_LtoN                    (SInt32                 value);
  130.  
  131. EXTERN_API_C( SInt32 )
  132. EndianS32_NtoL                    (SInt32                 value);
  133.  
  134. EXTERN_API_C( SInt32 )
  135. EndianS32_LtoB                    (SInt32                 value);
  136.  
  137. EXTERN_API_C( SInt32 )
  138. EndianS32_BtoL                    (SInt32                 value);
  139.  
  140. EXTERN_API_C( UInt32 )
  141. EndianU32_BtoN                    (UInt32                 value);
  142.  
  143. EXTERN_API_C( UInt32 )
  144. EndianU32_NtoB                    (UInt32                 value);
  145.  
  146. EXTERN_API_C( UInt32 )
  147. EndianU32_LtoN                    (UInt32                 value);
  148.  
  149. EXTERN_API_C( UInt32 )
  150. EndianU32_NtoL                    (UInt32                 value);
  151.  
  152. EXTERN_API_C( UInt32 )
  153. EndianU32_LtoB                    (UInt32                 value);
  154.  
  155. EXTERN_API_C( UInt32 )
  156. EndianU32_BtoL                    (UInt32                 value);
  157.  
  158. EXTERN_API_C( SInt64 )
  159. EndianS64_BtoN                    (SInt64                 value);
  160.  
  161. EXTERN_API_C( SInt64 )
  162. EndianS64_NtoB                    (SInt64                 value);
  163.  
  164. EXTERN_API_C( SInt64 )
  165. EndianS64_LtoN                    (SInt64                 value);
  166.  
  167. EXTERN_API_C( SInt64 )
  168. EndianS64_NtoL                    (SInt64                 value);
  169.  
  170. EXTERN_API_C( SInt64 )
  171. EndianS64_LtoB                    (SInt64                 value);
  172.  
  173. EXTERN_API_C( SInt64 )
  174. EndianS64_BtoL                    (SInt64                 value);
  175.  
  176. EXTERN_API_C( UInt64 )
  177. EndianU64_BtoN                    (UInt64                 value);
  178.  
  179. EXTERN_API_C( UInt64 )
  180. EndianU64_NtoB                    (UInt64                 value);
  181.  
  182. EXTERN_API_C( UInt64 )
  183. EndianU64_LtoN                    (UInt64                 value);
  184.  
  185. EXTERN_API_C( UInt64 )
  186. EndianU64_NtoL                    (UInt64                 value);
  187.  
  188. EXTERN_API_C( UInt64 )
  189. EndianU64_LtoB                    (UInt64                 value);
  190.  
  191. EXTERN_API_C( UInt64 )
  192. EndianU64_BtoL                    (UInt64                 value);
  193.  
  194.  
  195. /*
  196.     Macro away no-op functions
  197. */
  198. #if TARGET_RT_BIG_ENDIAN
  199.     #define EndianS16_BtoN(value)                (value)
  200.     #define EndianS16_NtoB(value)                (value)
  201.     #define EndianU16_BtoN(value)                (value)
  202.     #define EndianU16_NtoB(value)                (value)
  203.     #define EndianS32_BtoN(value)                (value)
  204.     #define EndianS32_NtoB(value)                (value)
  205.     #define EndianU32_BtoN(value)                (value)
  206.     #define EndianU32_NtoB(value)                (value)
  207.     #define EndianS64_BtoN(value)                (value)
  208.     #define EndianS64_NtoB(value)                (value)
  209.     #define EndianU64_BtoN(value)                (value)
  210.     #define EndianU64_NtoB(value)                (value)
  211. #else
  212.     #define EndianS16_LtoN(value)                (value)
  213.     #define EndianS16_NtoL(value)                (value)
  214.     #define EndianU16_LtoN(value)                (value)
  215.     #define EndianU16_NtoL(value)                (value)
  216.     #define EndianS32_LtoN(value)                (value)
  217.     #define EndianS32_NtoL(value)                (value)
  218.     #define EndianU32_LtoN(value)                (value)
  219.     #define EndianU32_NtoL(value)                (value)
  220.     #define EndianS64_LtoN(value)                (value)
  221.     #define EndianS64_NtoL(value)                (value)
  222.     #define EndianU64_LtoN(value)                (value)
  223.     #define EndianU64_NtoL(value)                (value)
  224. #endif
  225.  
  226.  
  227.  
  228. /*
  229.     Map native to actual
  230. */
  231. #if TARGET_RT_BIG_ENDIAN
  232.     #define EndianS16_LtoN(value)                EndianS16_LtoB(value)
  233.     #define EndianS16_NtoL(value)                EndianS16_BtoL(value)
  234.     #define EndianU16_LtoN(value)                EndianU16_LtoB(value)
  235.     #define EndianU16_NtoL(value)                EndianU16_BtoL(value)
  236.     #define EndianS32_LtoN(value)                EndianS32_LtoB(value)
  237.     #define EndianS32_NtoL(value)                EndianS32_BtoL(value)
  238.     #define EndianU32_LtoN(value)                EndianU32_LtoB(value)
  239.     #define EndianU32_NtoL(value)                EndianU32_BtoL(value)
  240.     #define EndianS64_LtoN(value)                EndianS64_LtoB(value)
  241.     #define EndianS64_NtoL(value)                EndianS64_BtoL(value)
  242.     #define EndianU64_LtoN(value)                EndianU64_LtoB(value)
  243.     #define EndianU64_NtoL(value)                EndianU64_BtoL(value)
  244. #else
  245.     #define EndianS16_BtoN(value)                EndianS16_BtoL(value)
  246.     #define EndianS16_NtoB(value)                EndianS16_LtoB(value)
  247.     #define EndianU16_BtoN(value)                EndianU16_BtoL(value)
  248.     #define EndianU16_NtoB(value)                EndianU16_LtoB(value)
  249.     #define EndianS32_BtoN(value)                EndianS32_BtoL(value)
  250.     #define EndianS32_NtoB(value)                EndianS32_LtoB(value)
  251.     #define EndianU32_BtoN(value)                EndianU32_BtoL(value)
  252.     #define EndianU32_NtoB(value)                EndianU32_LtoB(value)
  253.     #define EndianS64_BtoN(value)                EndianS64_BtoL(value)
  254.     #define EndianS64_NtoB(value)                EndianS64_LtoB(value)
  255.     #define EndianU64_BtoN(value)                EndianU64_BtoL(value)
  256.     #define EndianU64_NtoB(value)                EndianU64_LtoB(value)
  257. #endif
  258.  
  259.  
  260.  
  261. /*
  262.     Implement ≈LtoB and ≈BtoL
  263. */
  264. #define EndianS16_LtoB(value)                ((SInt16)Endian16_Swap(value))
  265. #define EndianS16_BtoL(value)                ((SInt16)Endian16_Swap(value))
  266. #define EndianU16_LtoB(value)                ((UInt16)Endian16_Swap(value))
  267. #define EndianU16_BtoL(value)                ((UInt16)Endian16_Swap(value))
  268. #define EndianS32_LtoB(value)                ((SInt32)Endian32_Swap(value))
  269. #define EndianS32_BtoL(value)                ((SInt32)Endian32_Swap(value))
  270. #define EndianU32_LtoB(value)                ((UInt32)Endian32_Swap(value))
  271. #define EndianU32_BtoL(value)                ((UInt32)Endian32_Swap(value))
  272. #define EndianS64_LtoB(value)                ((SInt64)Endian64_Swap((UInt64)value))
  273. #define EndianS64_BtoL(value)                ((SInt64)Endian64_Swap((UInt64)value))
  274. #define EndianU64_LtoB(value)                ((UInt64)Endian64_Swap(value))
  275. #define EndianU64_BtoL(value)                ((UInt64)Endian64_Swap(value))
  276.  
  277.  
  278.  
  279. /*
  280.     Implement low level ≈_Swap functions.
  281.     
  282.         extern UInt16 Endian16_Swap(UInt16 value);
  283.         extern UInt32 Endian32_Swap(UInt32 value);
  284.         extern UInt64 Endian64_Swap(UInt64 value);
  285.         
  286.     Note: Depending on the processor, you might want to implement
  287.           these as function calls instead of macros.
  288.     
  289. */
  290.  
  291. #if TARGET_CPU_68K && TARGET_OS_MAC
  292.     #pragma parameter __D0 Endian16_Swap(__D0)
  293.     pascal UInt16 Endian16_Swap(UInt16 value)
  294.         = { 0xE158 };
  295.     
  296.     #pragma parameter __D0 Endian32_Swap (__D0)
  297.     pascal UInt32 Endian32_Swap(UInt32 value)
  298.         = { 0xE158, 0x4840, 0xE158 };
  299. #else
  300.     #define Endian16_Swap(value)                 \
  301.             (((((UInt16)value)<<8) & 0xFF00)   | \
  302.              ((((UInt16)value)>>8) & 0x00FF))
  303.     
  304.     #define Endian32_Swap(value)                     \
  305.             (((((UInt32)value)<<24) & 0xFF000000)  | \
  306.              ((((UInt32)value)<< 8) & 0x00FF0000)  | \
  307.              ((((UInt32)value)>> 8) & 0x0000FF00)  | \
  308.              ((((UInt32)value)>>24) & 0x000000FF))
  309. #endif
  310.  
  311.  
  312. #if _LONG_LONG
  313.     #ifdef __MRC__
  314.         #define Endian64_Swap(value)                             \
  315.                 (((((UInt64)value)<<56) & 0xFF00000000000000ULL)  | \
  316.                  ((((UInt64)value)<<40) & 0x00FF000000000000ULL)  | \
  317.                  ((((UInt64)value)<<24) & 0x0000FF0000000000ULL)  | \
  318.                  ((((UInt64)value)<< 8) & 0x000000FF00000000ULL)  | \
  319.                  ((((UInt64)value)>> 8) & 0x00000000FF000000ULL)  | \
  320.                  ((((UInt64)value)>>24) & 0x0000000000FF0000ULL)  | \
  321.                  ((((UInt64)value)>>40) & 0x000000000000FF00ULL)  | \
  322.                  ((((UInt64)value)>>56) & 0x00000000000000FFULL))
  323.     #else
  324.         #define Endian64_Swap(value)                             \
  325.                 (((((UInt64)value)<<56) & 0xFF00000000000000)  | \
  326.                  ((((UInt64)value)<<40) & 0x00FF000000000000)  | \
  327.                  ((((UInt64)value)<<24) & 0x0000FF0000000000)  | \
  328.                  ((((UInt64)value)<< 8) & 0x000000FF00000000)  | \
  329.                  ((((UInt64)value)>> 8) & 0x00000000FF000000)  | \
  330.                  ((((UInt64)value)>>24) & 0x0000000000FF0000)  | \
  331.                  ((((UInt64)value)>>40) & 0x000000000000FF00)  | \
  332.                  ((((UInt64)value)>>56) & 0x00000000000000FF))
  333.     #endif
  334. #else
  335.     /* 
  336.         Note: When using C compilers that don't support "long long",
  337.               Endian64_Swap must be implemented as glue. 
  338.     */
  339.     #ifdef __cplusplus
  340.         inline static UInt64 Endian64_Swap(UInt64 value)
  341.         {
  342.             UInt64 temp;
  343.             temp.lo = Endian32_Swap(value.hi);
  344.             temp.hi = Endian32_Swap(value.lo);
  345.             return temp;
  346.         }
  347.     #else
  348.         extern UInt64 Endian64_Swap(UInt64 value);
  349.     #endif
  350. #endif
  351.  
  352.  
  353. #if PRAGMA_STRUCT_ALIGN
  354.     #pragma options align=reset
  355. #elif PRAGMA_STRUCT_PACKPUSH
  356.     #pragma pack(pop)
  357. #elif PRAGMA_STRUCT_PACK
  358.     #pragma pack()
  359. #endif
  360.  
  361. #ifdef PRAGMA_IMPORT_OFF
  362. #pragma import off
  363. #elif PRAGMA_IMPORT
  364. #pragma import reset
  365. #endif
  366.  
  367. #ifdef __cplusplus
  368. }
  369. #endif
  370.  
  371. #endif /* __ENDIAN__ */
  372.  
  373.